package com.zbs.framework.dao.phonevcode.service.impl;

import com.zbs.framework.common.utils.CommonUtil;
import com.zbs.framework.common.utils.ErrEnum;
import com.zbs.framework.common.utils.ErrorAssert;
import com.zbs.framework.dao.phonevcode.PhoneVCodeSettings;
import com.zbs.framework.dao.phonevcode.entity.PhoneVCode;
import com.zbs.framework.dao.phonevcode.repository.PhoneVCodeRepository;
import com.zbs.framework.dao.phonevcode.service.PhoneVCodeService;
import com.zbs.framework.dao.phonevcode.service.SMSService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * 
 * @author haohui_yao
 * 
 * @date 2017年4月15日
 */

@Service
@Transactional
public class PhoneVCodeServiceImpl implements PhoneVCodeService {

	@Autowired
	private PhoneVCodeRepository phoneVCodeRepository;

	@Autowired
	private PhoneVCodeSettings phoneVCodeSettings;

	@Autowired
	private SMSService smsService;

	@Override
	public void validatePhoneVCode(String phone, String vCode, String vType) {
		// 读取是否检查的配置
		this.validatePhoneVCode(true,phone,vCode,vType);
	}


	@Override
	public void validatePhoneVCode(boolean flag, String phone, String vCode, String vType) {
		// 读取是否检查的配置
		if (!phoneVCodeSettings.isDoValidate()) return;
		// 参数检查
		ErrorAssert.trimHasLength(phone, "手机号不能为空");
		ErrorAssert.trimHasLength(vCode, "验证码不能为空!");
		ErrorAssert.trimHasLength(vType, "验证码类型不能为空!");

		// 检查验证码
		PhoneVCode phoneVCode = phoneVCodeRepository.findByPhoneAndType(phone, vType);
		ErrorAssert.notNull(phoneVCode, ErrEnum.VCODE_NOT_CORRECT.getErrMsg());// 验证码不存在

		// 检查验证码是否正确
		ErrorAssert.isTrue(vCode.equals(phoneVCode.getCode()), ErrEnum.VCODE_NOT_CORRECT.getErrMsg());

		// 检查验证码是否失效
		long vCodeValidMs = phoneVCodeSettings.getValidPeriod();
		ErrorAssert.isTrue((new Date().getTime() - phoneVCode.getCreateTime().getTime()) <= vCodeValidMs,
				ErrEnum.VCODE_NOT_IN_VALID_PERIOD.getErrMsg());

		// 删除验证码
		this.phoneVCodeRepository.delete(phoneVCode);
	}

	/**
	 * 获取短信验证码
	 *
	 * @param phone
	 * @param vType
	 */
	@Override
	public void getPhoneVCode(String phone, String vType) {
		// 参数检查
		ErrorAssert.hasLength(vType, "VType can not be empty!");
		// 检查手机号格式
		ErrorAssert.isTrue(CommonUtil.matchPhone(phone), ErrEnum.PHONE_FORMAT_ERR);
		// 检查验证码
		PhoneVCode phoneVCode = phoneVCodeRepository.findByPhoneAndType(phone, vType);
		if (phoneVCode != null) {
			// 检查重复发送间隔是否过短
			long vCodeRepeatLimit = phoneVCodeSettings.getRepeatLimit();
			ErrorAssert.isTrue((new Date().getTime() - phoneVCode.getCreateTime().getTime()) > vCodeRepeatLimit,
					ErrEnum.GET_VCODE_INTERVAL_TOO_SHORT);
		}

		// 生成
		String randomCode = CommonUtil.getRandomNumString(6);
		// 保存验证码
		if (phoneVCode != null) {
			phoneVCode.setCode(randomCode);
			phoneVCode.setCreateTime(new Date());
		} else {
			phoneVCode = new PhoneVCode();
			phoneVCode.setPhone(phone);
			phoneVCode.setType(vType);
			phoneVCode.setCode(randomCode);
			phoneVCode.setCreateTime(new Date());
		}
		phoneVCodeRepository.save(phoneVCode);
		// TODO 调用短信接口
		smsService.sendSM(phone, randomCode,vType);
	}
}
